import 'dart:io';

import 'package:audioplayers/audioplayers.dart';
import 'package:bike_ride/common/store/unpay.dart';
import 'package:bike_ride/common/util/account_manager.dart';
import 'package:bike_ride/common/util/debouncer.dart';
import 'package:bike_ride/common/util/hysize_fit.dart';
import 'package:bike_ride/common/util/permission_utils.dart';
import 'package:bike_ride/common/widget/page_title_widget.dart';
import 'package:bike_ride/common/widget/super_button_widget.dart';
import 'package:bike_ride/generated/l10n.dart';
import 'package:bike_ride/res/style/color_styles.dart';
import 'package:bike_ride/router/navigator_util.dart';
import 'package:bike_ride/router/routers.dart';
import 'package:flutter/material.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:mobile_scanner/mobile_scanner.dart';

goToUnLockPage(BuildContext context, String vid) {
  if(vid.isNotEmpty){
    NavigatorUtil.push(context, Routers.unLockView, arguments: vid);
  }
}

class EnterCodePage extends StatefulWidget {
  const EnterCodePage({super.key});

  @override
  State<EnterCodePage> createState() => _EnterCodePageState();
}

class _EnterCodePageState extends State<EnterCodePage> {
  final _controller = TextEditingController();

  final unPayStore = UnPay();

  @override
  void initState() {
    super.initState();
    unPayStore.getUnPayOrder();
  }

  @override
  void dispose() {
    super.dispose();
    _controller.dispose();
  }


  @override
  Widget build(BuildContext context) {
    return Scaffold(
      extendBodyBehindAppBar: true,
      backgroundColor: ColorStyles.color_F3F4F5,
      body: SingleChildScrollView(
        keyboardDismissBehavior: ScrollViewKeyboardDismissBehavior.onDrag,
        child: Column(
          children: [
            PageTitleWidget(title: S.current.enterCodeUnlockCar),
            Image.asset(
              'assets/common_v2/codeUnlock_v2.png',
              fit: BoxFit.fitWidth,
            ),
            Padding(
              padding: EdgeInsets.symmetric(horizontal: 28.rpx),
              child: Column(
                children: [
                  SizedBox(
                    height: 32.rpx,
                  ),
                  TextField(
                    controller: _controller,
                    textAlign: TextAlign.center,
                    decoration: InputDecoration(
                      hintText: S.current.pleasePrintInCode,
                      hintStyle: const TextStyle(
                          fontSize: 16, color: ColorStyles.color_333333),
                      focusedBorder: const UnderlineInputBorder(
                        borderSide: BorderSide(color: Colors.black),
                      ),
                      enabledBorder: const UnderlineInputBorder(
                        borderSide: BorderSide(color: Colors.black12),
                      ),
                    ),
                  ),
                  SizedBox(
                    height: 32.rpx,
                  ),
                  SuperButtonWidget(
                    btnText: S.current.unlockNow,
                    onPressed: () {
                      if(unPayStore.unPayOrderList.length >= (AccountManager.brandInfo?.currentOrderNum??1)){
                        unPayStore.showTipDialog();
                        return;
                      }
                      if (_controller.text.isNotEmpty) {
                        // NavigatorUtil.back(context,arguments: _controller.text.trim());
                        goToUnLockPage(context, _controller.text.trim());
                      }else{
                        EasyLoading.showError(S.current.pleasePrintInCode);
                      }
                    },
                  ),
                  SizedBox(
                    height: 20.rpx,
                  ),
                  SuperButtonWidget(
                    btnText: S.current.goBack,
                    bgColor:Colors.black12,
                    textColor: Colors.black45,
                    onPressed: () {
                      NavigatorUtil.back(context);
                    },
                  )
                ],
              ),
            ),
          ],
        ),
      ),
    );
  }
}

class QrcodeScanPage extends StatefulWidget {
  const QrcodeScanPage({Key? key}) : super(key: key);

  @override
  State<QrcodeScanPage> createState() => _QrcodeScanPageState();
}

class _QrcodeScanPageState extends State<QrcodeScanPage>
    with SingleTickerProviderStateMixin {
  MobileScannerController? controller;
  final GlobalKey qrKey = GlobalKey(debugLabel: 'QR');
  final AudioPlayer audioPlayer = AudioPlayer(); //扫码成功后发出手机提示音
  late AssetSource assetSource;

  bool flashStatus = false;
  final bool _isBarCode = false;

  //MobileScanner实例存在复用情况，重新偶尔会复用上一次的实例，丢除第一次的数据
  bool isFirst = true;

  requestPermission() {
    //申请相机权限
    PermissionUtil.handleCameraPermission(context, (success, msg) {
      if (success) {
        controller = MobileScannerController(
          torchEnabled: false,
          formats: Platform.isAndroid
              ? [BarcodeFormat.qrCode, BarcodeFormat.code128]
              : [BarcodeFormat.all],
        );
        setState(() {});
      } else {
        EasyLoading.showError(msg);
      }
    });
  }

  @override
  void initState() {
    requestPermission();
    super.initState();

    assetSource = AssetSource('common/tips_di.mp3');
  }

  @override
  void dispose() {
    controller?.dispose();
    controller = null;
    super.dispose();
  }

  void customPop(String result) async {
    Future.delayed(const Duration(milliseconds: 100)).then((value) {
      if (context.mounted) Navigator.pop(context, result);
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Stack(
        children: [
          Column(
            children: [Expanded(flex: 1, child: _buildQrView(context))],
          ),
          Positioned(
            top: 0,
            left: 0,
            right: 0,
            bottom: 0,
            child: Container(
              decoration: ShapeDecoration(
                shape: QrScannerOverlayShape(
                    borderColor: Theme.of(context).colorScheme.primary,
                    borderWidth: 12.rpx,
                    borderLength: 35.rpx,
                    cutOutBottomOffset: MediaQuery.of(context).size.height *
                        (!!_isBarCode ? 0.2 : 0.15),
                    cutOutSize: 464.rpx,
                    isRectangle: _isBarCode),
              ),
            ),
          ),
          Positioned(
            top: 80.rpx,
            right: 20.rpx,
            left: 20.rpx,
            child: SizedBox(
              height: 50.rpx,
              child: Row(
                mainAxisAlignment: MainAxisAlignment.spaceBetween,
                crossAxisAlignment: CrossAxisAlignment.center,
                children: [
                  BackButton(
                    color: Colors.white,
                    onPressed: () {
                      Navigator.pop(context);
                    },
                  ),
                ],
              ),
            ),
          ),
          Positioned(
            top: MediaQuery.of(context).size.height / 2 +
                50.rpx +
                (!!_isBarCode ? 300.rpx : 0),
            left: 20.rpx,
            right: 20.rpx,
            child: Column(
              children: [
                Text(
                  !!_isBarCode ? '横着对准条形码进行识别' : S.current.scanVehicleCode,
                  style: TextStyle(
                    fontSize: 24.rpx,
                    color: Colors.white,
                    fontWeight: FontWeight.w500,
                  ),
                ),
              ],
            ),
          ),
          Positioned(
            left: 0,
            right: 0,
            bottom: 0,
            child: Container(
              padding:
                  EdgeInsets.symmetric(vertical: 50.rpx, horizontal: 50.rpx),
              color: Colors.black.withOpacity(0.5),
              child: Column(
                mainAxisSize: MainAxisSize.min,
                children: [
                  Row(
                    mainAxisAlignment: MainAxisAlignment.spaceBetween,
                    children: [
                      GestureDetector(
                        onTap: () {
                          controller?.stop();
                          NavigatorUtil.push(context, Routers.enterCodePage)
                              .then((value) {
                            if (value != null) {
                              customPop(value as String);
                            } else {
                              Navigator.pop(context);
                            }
                          });
                        },
                        child: Column(
                          children: [
                            Container(
                              width: 100.rpx,
                              height: 100.rpx,
                              decoration: const BoxDecoration(
                                  image: DecorationImage(
                                fit: BoxFit.contain,
                                image: AssetImage(
                                    'assets/images/keyboard-bg.webp'),
                              )),
                            ),
                            SizedBox(
                              height: 12.rpx,
                            ),
                            Text(
                              S.current.handInCode,
                              style: TextStyle(
                                fontSize: 24.rpx,
                                color: Colors.white,
                                fontWeight: FontWeight.w500,
                              ),
                            ),
                          ],
                        ),
                      ),
                      GestureDetector(
                        onTap: () {
                          if (controller == null) {
                            requestPermission();
                          } else {
                            if (controller?.hasTorchState.value != null) {
                              controller?.toggleTorch();
                            }
                          }
                        },
                        child: ValueListenableBuilder(
                          valueListenable: controller?.torchState ??
                              ValueNotifier(TorchState.off),
                          builder: (context, state, child) {
                            return Column(
                              children: [
                                Container(
                                  width: 100.rpx,
                                  height: 100.rpx,
                                  decoration: BoxDecoration(
                                      image: DecorationImage(
                                    fit: BoxFit.contain,
                                    image: AssetImage(state == TorchState.on
                                        ? 'assets/images/light-on-bg.webp'
                                        : 'assets/images/light-bg.webp'),
                                  )),
                                ),
                                SizedBox(
                                  height: 12.rpx,
                                ),
                                Text(
                                  '${state == TorchState.on ? S.current.close : S.current.open}${S.current.flashLight}',
                                  style: TextStyle(
                                    fontSize: 24.rpx,
                                    color: Colors.white,
                                    fontWeight: FontWeight.w500,
                                  ),
                                ),
                              ],
                            );
                          },
                        ),
                      )
                    ],
                  ),
                ],
              ),
            ),
          ),
        ],
      ),
    );
  }

  Widget _buildQrView(BuildContext context) {
    if (controller == null) return Container();
    return MobileScanner(
      key: qrKey,
      controller: controller,
      onDetect: (BarcodeCapture barcodes) {
        if (isFirst) {
          isFirst = false;
          return;
        }

        List<String> results = [];
        for (final barcode in barcodes.barcodes) {
          if (barcode.rawValue == null ||
              barcode.rawValue!.isEmpty ||
              results.contains(barcode.rawValue)) continue;
          results.add(barcode.rawValue!);
        }

        SingleCall.call(delayTime: const Duration(milliseconds: 500), () {
          if (results.isEmpty) return;
          final mValue = results.toSet().toList();
          customPop(mValue.last);
        });
      },
    );
  }
}

class QrScannerOverlayShape extends ShapeBorder {
  const QrScannerOverlayShape(
      {this.borderColor = Colors.red,
      this.borderWidth = 3.0,
      this.overlayColor = const Color.fromRGBO(0, 0, 0, 0.7),
      this.borderRadius = 0,
      this.borderLength = 40,
      this.cutOutSize = 250,
      this.cutOutBottomOffset = 0,
      this.isRectangle = false})
      : assert(borderLength <= cutOutSize / 2 + borderWidth * 2,
            "Border can't be larger than ${cutOutSize / 2 + borderWidth * 2}");

  final Color borderColor;
  final double borderWidth;
  final Color overlayColor;
  final double borderRadius;
  final double borderLength;
  final double cutOutSize;
  final double cutOutBottomOffset;
  final bool isRectangle;

  @override
  EdgeInsetsGeometry get dimensions => const EdgeInsets.all(10);

  @override
  Path getInnerPath(Rect rect, {TextDirection? textDirection}) {
    return Path()
      ..fillType = PathFillType.evenOdd
      ..addPath(getOuterPath(rect), Offset.zero);
  }

  @override
  Path getOuterPath(Rect rect, {TextDirection? textDirection}) {
    Path getLeftTopPath(Rect rect) {
      return Path()
        ..moveTo(rect.left, rect.bottom)
        ..lineTo(rect.left, rect.top)
        ..lineTo(rect.right, rect.top);
    }

    return getLeftTopPath(rect)
      ..lineTo(
        rect.right,
        rect.bottom,
      )
      ..lineTo(
        rect.left,
        rect.bottom,
      )
      ..lineTo(
        rect.left,
        rect.top,
      );
  }

  @override
  void paint(Canvas canvas, Rect rect, {TextDirection? textDirection}) {
    final width = rect.width;
    final borderWidthSize = width / 2;
    final height = rect.height;
    final borderOffset = borderWidth / 2;
    final borderLength_ = borderLength > cutOutSize / 2 + borderWidth * 2
        ? borderWidthSize / 2
        : borderLength;
    final cutOutSize_ = cutOutSize < width ? cutOutSize : width - borderOffset;

    final backgroundPaint = Paint()
      ..color = overlayColor
      ..style = PaintingStyle.fill;

    final borderPaint = Paint()
      ..color = borderColor
      ..style = PaintingStyle.stroke
      ..strokeWidth = borderWidth;

    final boxPaint = Paint()
      ..color = borderColor
      ..style = PaintingStyle.fill
      ..blendMode = BlendMode.dstOut;

    final cutOutRect = Rect.fromLTWH(
      rect.left + width / 2 - cutOutSize_ / 2 + borderOffset,
      -cutOutBottomOffset +
          rect.top +
          height / 2 -
          cutOutSize_ / 2 +
          borderOffset,
      cutOutSize_ - borderOffset * 2,
      cutOutSize_ - borderOffset * 2 + (!!isRectangle ? 380.rpx : 0),
    );

    canvas
      ..saveLayer(
        rect,
        backgroundPaint,
      )
      ..drawRect(
        rect,
        backgroundPaint,
      )
      // Draw top right corner
      ..drawRRect(
        RRect.fromLTRBAndCorners(
          cutOutRect.right - borderLength_,
          cutOutRect.top,
          cutOutRect.right,
          cutOutRect.top + borderLength_,
          topRight: Radius.circular(borderRadius),
        ),
        borderPaint,
      )
      // Draw top left corner
      ..drawRRect(
        RRect.fromLTRBAndCorners(
          cutOutRect.left,
          cutOutRect.top,
          cutOutRect.left + borderLength_,
          cutOutRect.top + borderLength_,
          topLeft: Radius.circular(borderRadius),
        ),
        borderPaint,
      )
      // Draw bottom right corner
      ..drawRRect(
        RRect.fromLTRBAndCorners(
          cutOutRect.right - borderLength_,
          cutOutRect.bottom - borderLength_,
          cutOutRect.right,
          cutOutRect.bottom,
          bottomRight: Radius.circular(borderRadius),
        ),
        borderPaint,
      )
      // Draw bottom left corner
      ..drawRRect(
        RRect.fromLTRBAndCorners(
          cutOutRect.left,
          cutOutRect.bottom - borderLength_,
          cutOutRect.left + borderLength_,
          cutOutRect.bottom,
          bottomLeft: Radius.circular(borderRadius),
        ),
        borderPaint,
      )
      ..drawRRect(
        RRect.fromRectAndRadius(
          cutOutRect,
          Radius.circular(borderRadius),
        ),
        boxPaint,
      )
      ..restore();
  }

  @override
  ShapeBorder scale(double t) {
    return QrScannerOverlayShape(
      borderColor: borderColor,
      borderWidth: borderWidth,
      overlayColor: overlayColor,
    );
  }
}
